package name.jautzy.esi.client;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import name.jautzy.esi.client.model.EdbAttribute;
import name.jautzy.esi.client.model.EdbBonus;
import name.jautzy.esi.client.model.EdbEffect;
import name.jautzy.esi.client.model.EdbEquipment;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.TreeGridEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.CheckColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.event.ButtonEvent; 
import com.google.gwt.user.client.rpc.AsyncCallback;

public class DisplayDbEquipmentListener implements Listener<TreeGridEvent<ModelData>>{
	private ContentPanel parent;

	public DisplayDbEquipmentListener (ContentPanel parent) {
		this.parent = parent;
	}

	public void handleEvent(TreeGridEvent<ModelData> ce) {
		ModelData model = ce.getModel();
		if (! (model instanceof EdbEquipment))
			return;
		EdbEquipment equip = (EdbEquipment)model;
		ContentPanel panel = new ContentPanel();
		panel.setHeading(equip.getName());
		panel.setLayout(new FitLayout());

		TabPanel tabs = new TabPanel();
		TabItem baseTab = new TabItem("Description");
		baseTab.addText("<p style=\"color:black\">"+equip.getDescription()+"</p>");

		TabItem effTab = new TabItem("Effects");
		createEffTab(effTab,equip);

		TabItem attTab = new TabItem("Attributes");
		createAttTab(attTab,equip);

		TabItem bonusTab = new TabItem("Bonus");
		createBonusTab(bonusTab,equip);


		tabs.add(baseTab);
		tabs.add(effTab);
		tabs.add(attTab);
		tabs.add(bonusTab);

		panel.add(tabs);

		parent.removeAll();  
		parent.add(panel);  
		parent.layout(); 
	}

	void createAttTab(TabItem attTab, final EdbEquipment equip) {
		attTab.setLayout(new FitLayout());

		RpcProxy<List<EdbAttribute>> sProxy = new RpcProxy<List<EdbAttribute>> () {
			@Override
			public void load(Object loadconfig, AsyncCallback<List<EdbAttribute>> callback) {
				Esi.getEsi().getDatabaseService().getAttributes(equip, callback);
			}
		};
		ListLoader<ListLoadResult<EdbAttribute>> sLoader = new BaseListLoader<ListLoadResult<EdbAttribute>>(sProxy);
		ListStore<EdbAttribute> sStore = new ListStore<EdbAttribute>(sLoader);
		sLoader.load();

		List<ColumnConfig> columns = new ArrayList<ColumnConfig>();  
		columns.add(new ColumnConfig("name", "Name", 300));  
		columns.add(new ColumnConfig("value", "Value", 100));
		ColumnModel cm = new ColumnModel(columns);

		Grid<EdbAttribute> grid = new Grid<EdbAttribute>(sStore,cm);

		attTab.add(grid);


	}

	void createBonusTab(TabItem bonusTab, final EdbEquipment equip) {
		bonusTab.setLayout(new FitLayout());
		RpcProxy<List<EdbBonus>> sProxy = new RpcProxy<List<EdbBonus>> () {
			@Override
			public void load(Object loadconfig, AsyncCallback<List<EdbBonus>> callback) {
				Esi.getEsi().getDatabaseService().getBonus(equip, callback);
			}
		};
		ListLoader<ListLoadResult<EdbBonus>> sLoader = new BaseListLoader<ListLoadResult<EdbBonus>>(sProxy);
		final ListStore<EdbBonus> sStore = new ListStore<EdbBonus>(sLoader);
		sLoader.load();

		List<ColumnConfig> columns = new ArrayList<ColumnConfig>();  
		CheckColumnConfig checkColumn = new CheckColumnConfig("selected", "", 35);  
		CellEditor checkBoxEditor = new CellEditor(new CheckBox());  
		checkColumn.setEditor(checkBoxEditor);  
		columns.add(checkColumn);

		ColumnConfig column = new ColumnConfig();
		column.setId("name");
		column.setHeader("Name");
		column.setWidth(300);
		TextField<String> text = new TextField<String>();  
		text.setAllowBlank(false);  
		column.setEditor(new CellEditor(text));  
		columns.add(column);  

		column = new ColumnConfig();
		column.setId("value");
		column.setHeader("Value");
		column.setAlignment(HorizontalAlignment.RIGHT);  
		column.setWidth(100); 
		column.setEditor(new CellEditor(new NumberField()));  
		columns.add(column);
		ColumnModel cm = new ColumnModel(columns);

		column = new ColumnConfig();
		column.setId("skill");
		column.setHeader("Skill");
		column.setAlignment(HorizontalAlignment.RIGHT);  
		column.setWidth(50); 
		column.setEditor(new CellEditor(new NumberField()));  
		columns.add(column);

		
		

		ContentPanel cp = new ContentPanel();
		cp.setHeaderVisible(false);
		cp.setLayout(new FitLayout());
		

		if (Esi.getEsi().getLoginInfo().isAdmin()) {
			final EditorGrid<EdbBonus> grid = new EditorGrid<EdbBonus>(sStore,cm);
			grid.addPlugin(checkColumn);
			cp.addButton(new Button("Reset", new SelectionListener<ButtonEvent>() {    	  
				@Override  
				public void componentSelected(ButtonEvent ce) {  
					sStore.rejectChanges();  
				}
			}));
			Button remove = new Button("Remove");
			remove.addSelectionListener(new SelectionListener<ButtonEvent>() {  
				@Override  
				public void componentSelected(ButtonEvent ce) {
					grid.stopEditing();
					List<EdbBonus> selected = new LinkedList<EdbBonus>();

					for (EdbBonus b :sStore.getModels()) {
						if (b.getSelected()) {
							sStore.remove(b);
							selected.add(b);
						}
					}

					AsyncCallback<Void> callback = new AsyncCallback<Void>() {
						public void onSuccess(Void result) {
							sStore.commitChanges();  
						}

						public void onFailure(Throwable caught) {
							MessageBox.info("Action", "Can't remove bonuses : "+caught.toString(), null); 
						}
					};
					Esi.getEsi().getDatabaseService().removeBonus(selected, callback);


				}  
			}); 
			cp.addButton(remove);
			Button add = new Button("Add");
			add.addSelectionListener(new SelectionListener<ButtonEvent>() {  
				@Override  
				public void componentSelected(ButtonEvent ce) {  
					EdbBonus bonus = new EdbBonus();
					bonus.setId(null);
					bonus.setName("");
					bonus.setSkill(1);
					bonus.setValue(0);

					grid.stopEditing(false);  
					sStore.insert(bonus, 0);  
					grid.startEditing(sStore.indexOf(bonus), 0);  
				}  
			}); 
			cp.addButton(add);
			cp.addButton(new Button("Save", new SelectionListener<ButtonEvent>() {    	  
				@Override  
				public void componentSelected(ButtonEvent ce) {  
					List<Record> modified = sStore.getModifiedRecords();
					List<EdbBonus> bonuses = new LinkedList<EdbBonus>();
					for (Record r:modified)
						bonuses.add((EdbBonus)r.getModel());
					AsyncCallback<Void> callback = new AsyncCallback<Void>() {
						public void onSuccess(Void result) {
							sStore.commitChanges();  
						}

						public void onFailure(Throwable caught) {
							MessageBox.info("Action", "Can't update bonuses : "+caught.toString(), null); 
						}
					};
					Esi.getEsi().getDatabaseService().updateBonus(bonuses, equip, callback);   
				}
			}));
			cp.add(grid);
		}
		else {
			final Grid<EdbBonus> grid = new Grid<EdbBonus>(sStore,cm);
			//grid.addPlugin(checkColumn);
			cp.add(grid);
		}
		
		bonusTab.add(cp);

	}

	void createEffTab(TabItem effTab, final EdbEquipment equip) {
		effTab.setLayout(new FitLayout());
		RpcProxy<List<EdbEffect>> sProxy = new RpcProxy<List<EdbEffect>> () {
			@Override
			public void load(Object loadconfig, AsyncCallback<List<EdbEffect>> callback) {
				Esi.getEsi().getDatabaseService().getEffects(equip, callback);
			}
		};
		ListLoader<ListLoadResult<EdbEffect>> sLoader = new BaseListLoader<ListLoadResult<EdbEffect>>(sProxy);
		ListStore<EdbEffect> sStore = new ListStore<EdbEffect>(sLoader);
		sLoader.load();

		List<ColumnConfig> columns = new ArrayList<ColumnConfig>();  
		columns.add(new ColumnConfig("name", "Name", 300));  
		columns.add(new ColumnConfig("offensive", "Is Offensive ?", 100));
		columns.add(new ColumnConfig("assistance", "Is Assistance ?", 100));
		ColumnModel cm = new ColumnModel(columns);

		Grid<EdbEffect> grid = new Grid<EdbEffect>(sStore,cm);

		effTab.add(grid);
	}

}
